﻿using System;
using PropertyExpression.Common;

namespace PropertyExpression.ControllableQuery.Demo
{
    public interface ITagSynonym
    {
        int Id { get; }
        string SourceTagName { get; }
        string TargetTagName { get; }
        int? OwnerUserId { get; }
        DateTime? ApprovalDate { get; }
        DateTime? CreationDate { get; }
        int? AutoRenameCount { get; }
        int? Score { get; }
        int? SourceTagId { get; }
        int? TargetTagId { get; }
        string DisplayName { get; }
    }

    class SomeClass2
    {
        void Method1()
        {
            Filter? filter = Filter.Suggested;
            Option<string> search = "%test%";
            var paging = BatchQuery<Paging<ITagSynonym, int?>>.New(new {
                filter, user = new {IsAnonymous = false, IsModerator = false, Id = 1}, tagScoreRequiredToVote = 10,
                search, tab = Tab.Newest, start = 0, pageSize = 20
            }, @"
SELECT  TagSynonyms.Id, SourceTagName, TargetTagName, OwnerUserId, ApprovalDate, TagSynonyms.CreationDate,
        AutoRenameCount, Score, SourceTags.Id AS SourceTagId, TargetTags.Id AS TargetTagId, Users.DisplayName
@MainQuery()
ORDER BY
@switch (tab) {
    case Tab.Newest:
        @:CreationDate DESC, Id
        break;
    case Tab.Master:
        @:TargetTagName ASC, AutoRenameCount DESC, Id
        break;
    case Tab.Synonym:
        @:SourceTagName ASC, AutoRenameCount DESC, Id
        break;
    case Tab.Votes:
        @:Score DESC, TargetTagName ASC, AutoRenameCount DESC, Id
        break;
    case Tab.Creator:
        @:DisplayName, Id
        break;
    case Tab.Renames:
        @:AutoRenameCount DESC, TargetTagName, Id
        break;
}
OFFSET @start ROWS FETCH NEXT @pageSize ROWS ONLY
OPTION (OPTIMIZE FOR (@start = 0, @pageSize = 20));
SELECT COUNT(*) @MainQuery();
@helper MainQuery() {<text>
FROM    TagSynonyms
        LEFT JOIN Tags SourceTags ON SourceTagName = SourceTags.Name
        LEFT JOIN Tags TargetTags ON TargetTagName = TargetTags.Name
        LEFT JOIN Users ON Users.Id = OwnerUserId
WHERE   1 = 1
@switch (filter) {
    case Filter.Active:
        @:AND ApprovalDate IS NOT NULL
        break;
    case Filter.Suggested:
        @:AND ApprovalDate IS NULL
        if (!user.IsAnonymous && !user.IsModerator) {
        @:AND TargetTagName IN (@TargetTagNames())
        }
        break;
    case Filter.Merge:
        @:AND ApprovalDate IS NOT NULL AND ISNULL(SourceTags.Count, 0) > 0
        break;
}
@if (search.HasValue) {
        @:AND (SourceTagName LIKE @search OR TargetTagName LIKE @search)
}
</text>}
@helper TargetTagNames() {<text>
SELECT  Name
FROM    Tags
WHERE   Id IN (SELECT   Id
               FROM     UserTagTotals
               WHERE    UserId = @user.Id
                        AND TotalAnswerScort > @tagScoreRequiredToVote)
</text>}").Result();
            var rows = paging.Rows;
            var count = paging.Count;
        }
    }

    public enum Tab
    {
        Newest,
        Master,
        Synonym,
        Votes,
        Creator,
        Renames
    }

    public enum Filter
    {
        Active,
        Suggested,
        Merge
    }
}